package com.lb.dao.redis;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationListener;
import org.springframework.data.redis.core.RedisKeyExpiredEvent;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.lang.NonNull;

import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * Redis Key 过期事件分发器
 *
 * @author xiemingzhi
 * @since 2.0.0
 */
@Slf4j
public class RedisKeyExpiredEventDispatcher<T> implements ApplicationListener<RedisKeyExpiredEvent<T>> {

    private final StringRedisTemplate stringRedisTemplate;
    private final List<RedisKeyExpiredListener> listeners;

    public RedisKeyExpiredEventDispatcher(StringRedisTemplate stringRedisTemplate, List<RedisKeyExpiredListener> listeners) {
        this.stringRedisTemplate = stringRedisTemplate;
        this.listeners = listeners;
    }

    @Override
    public void onApplicationEvent(@NonNull RedisKeyExpiredEvent<T> event) {
        if (listeners == null || listeners.isEmpty()) {
            return;
        }
        String key = new String(event.getId(), StandardCharsets.UTF_8);
//        log.info("监听到过期key:{},时间{}", key,LocalDateTime.now().format(FORMATTER_YYYY_MM_DDHH_MM_SS));
        Object value = event.getValue();
        int size = listeners.size();
        for (int i = 0; i < size; i++) {
            RedisKeyExpiredListener listener = listeners.get(i);
            if (listener.match(key)) {
                Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent("lock_" + (i + 1) + "_" + key, "ok", listener.timeout());
                if (lock == null) {
                    log.info("无法正确加锁，监听的过期key:{}", key);
                } else {
                    if (lock) {
                        listener.execute(key, value);
                    } else {
                        log.info("锁已存在，监听的过期key:{}", key);
                    }
                }

            }
        }
    }
}
